﻿/*******************************************************************************
 * Copyright © 2016 NFine.Framework 版权所有
 * Author: NFine
 * Description: NFine快速开发平台
 * Website：http://www.nfine.cn
*********************************************************************************/
using NFine.Code;
using NFine.Data.DBContext;
using SqlSugarRepository;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;

namespace NFine.Data
{
    /// <summary>
    /// 仓储实现
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class RepositoryBase<TEntity> : IRepositoryBase<TEntity> where TEntity : class,new()
    {
        ISqlSugarClient dbcontext = SugarDbContext.GetInstance();
        #region 新增
        /// <summary>
        /// 新增单条数据
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Insert(TEntity entity)
        {
            var result = dbcontext.Insert<TEntity>(entity);
            return result == null ? false : true;
        }

        /// <summary>
        /// 新增多条记录（批量插入 适合海量数据插入）
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public bool Insert(List<TEntity> entitys)
        {
            dbcontext.InsertRange(entitys);
            return true;
        }
        #endregion

        #region 更新
        /// <summary>
        /// 根据表达式条件将对象更新到数据库(部分字段更新)
        /// </summary>
        /// <param name="rowObj">匿名对象rowObj为匿名对象时只更新指定列( 例如:new{ name='abc'}只更新name )，为T类型将更新整个实体(排除主键、自增列和禁止更新列)</param>
        /// <param name="filterExpression">表达式条件</param>
        /// <returns>true |false </returns>
        public bool Update(object rowObj, Expression<Func<TEntity, bool>> filterExpression)
        {
            bool result = dbcontext.Update<TEntity>(rowObj, filterExpression);
            return result;
        }

        /// <summary>
        /// 根据实体更新(部分字段更新)
        /// 原有功能为全字段更新，现调整为部分字段更新；
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>true |false </returns>
        public bool Update(TEntity entity)
        {
            List<string> list = new List<string>();
            PropertyInfo[] props = entity.GetType().GetProperties();
            foreach (PropertyInfo prop in props)
            {
                if (prop.GetValue(entity, null) == null)
                {
                    list.Add(prop.Name);
                    continue;
                }
                if (prop.GetValue(entity, null).ToString() == "&nbsp;")
                {
                    entity.GetType().GetProperty(prop.Name).SetValue(entity, null, null);
                }
            }
            //清空禁止更新列
            dbcontext.DisableUpdateColumns = null;
            //添加禁用列参数
            dbcontext.AddDisableUpdateColumns(list.ToArray());
            dbcontext.RemoveAllCache<TEntity>();
            return dbcontext.Update<TEntity>(entity);
        }



        #endregion

        #region 删除
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(TEntity entity)
        {
            return dbcontext.Delete<TEntity>(entity);
        }

        /// <summary>
        /// 根据表达式删除数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">表达式条件</param>
        /// <returns>删除成功返回true</returns>
        public bool Delete(Expression<Func<TEntity, bool>> filterExpression)
        {
            return dbcontext.Delete<TEntity>(filterExpression);
        }
        #endregion

        #region 假删除

        /// <summary>
        /// 假删除
        /// </summary>
        /// <param name="keyvalue"></param>
        /// <returns></returns>
        public bool FalseDelete(string keyvalue)
        {
            return dbcontext.Update<TEntity, string>(new { F_DELETEMARK = "1" }, keyvalue);
        }


        /// <summary>
        /// 假删除根据实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool FalseDelete(TEntity entity)
        {
            return this.Update(entity);
        }

        #endregion

        #region 实体

        /// <summary>
        /// 根据主键查询
        /// </summary>
        /// <param name="keyValue">主键</param>
        /// <returns></returns>
        public TEntity FindEntity(object keyValue)
        {
            return dbcontext.Queryable<TEntity>().InSingle(keyValue);
        }

        /// <summary>
        /// 返回序列中的第一条记录,如果序列为NULL返回default(T)
        /// </summary>
        /// <param name="predicate">表达式条件</param>
        /// <returns></returns>
        public TEntity FindEntity(Expression<Func<TEntity, bool>> predicate)
        {
            return dbcontext.Queryable<TEntity>().Where(predicate).FirstOrDefault();
        }
        #endregion

        #region 查询
        public ISugarQueryable<TEntity> IQueryable()
        {
            return dbcontext.Queryable<TEntity>();
        }
        public ISugarQueryable<TEntity> IQueryable(string tableName)
        {
            return dbcontext.Queryable<TEntity>(tableName);
        }
        public ISugarQueryable<TEntity> IQueryable(Expression<Func<TEntity, bool>> predicate)
        {
            return dbcontext.Queryable<TEntity>().Where(predicate);
        }
        public List<TEntity> FindList(string strSql)
        {
            return dbcontext.SqlQuery<TEntity>(strSql);
        }
        public List<TEntity> FindList(string strSql, object dbParameter)
        {
            return dbcontext.SqlQuery<TEntity>(strSql, dbParameter).ToList<TEntity>();
        }

        public List<TEntity> FindList(Expression<Func<TEntity, bool>> predicate)
        {
            return dbcontext.Queryable<TEntity>().Where(predicate).ToList();
        }

        public List<TEntity> FindList(Pagination pagination)
        {
            //获取排序字段
            string order = Pagination.GetOrder(pagination);
            pagination.records = dbcontext.Queryable<TEntity>().Count();
            return dbcontext.Queryable<TEntity>().OrderBy(order).ToPageList(pagination.page, pagination.rows);
        }

        public List<TEntity> FindList(Expression<Func<TEntity, bool>> predicate, Pagination pagination, string extWhere = "")
        {
            //获取排序字段
            string order = Pagination.GetOrder(pagination);

            var query = dbcontext.Queryable<TEntity>().Where(predicate);
            if (!string.IsNullOrEmpty(extWhere))
            {
                query.Where(extWhere);
            }

            //总数
            pagination.records = query.Count();
            return query.OrderBy(order).ToPageList(pagination.page, pagination.rows);
        }
        #endregion
    }
}
